import Util from "../core/Util";
import YYYConfig from "../core/YYYConfig";

// 组件所用到事件
const DOWN = "touchstart";
const MOVE = "joystick_move";
const UP   = "joystick_up";
const OUT  = "touchendoutside";

interface JoystickConfig{
        ////
    //虚拟摇杆
    ////
    /**
     * 虚拟摇杆背景
     * **/
    joystick_wrap_img:string;
    /**虚拟摇杆按键*/
    joystick_button_img:string;

    joystick_width:number;
    joystick_height:number;
    joystick_position_x:number;
    /**摇杆的Y坐标,如果是负数,表示从底部向上偏移*/
    joystick_position_y:number;
}

/**
 * @constructor
 * 虚拟摇杆类
 */
export default class JoyStick extends Laya.Sprite {

    directionCount:number;
    directionDegree:number;
    currentDegree:number;
    halfDirection:number;
    touchId:number;
    hasDisable:boolean;

    button:Laya.Sprite;
    wrap:Laya.Sprite;
    lastStageX:number;
    lastStageY:number;
    radius:number;
    tweener:Laya.Tween;
    center:{x:number,y:number};
    config:JoystickConfig;
	/**
	 * 通过这个函数告知外界当前虚拟摇杆的状态
	 */
	constructor(config:JoystickConfig) {
        super();
        this.config = config;
		this.init();
	}

	init() {
        this.directionCount  = 360;
        this.directionDegree = 360 / this.directionCount;
        this.currentDegree   = 0;
        this.halfDirection   = 360 / this.directionCount / 2;
        
		// 用于限制区域内不能进行多点触控
		this.touchId = -1;

		// 	标识当前虚拟摇杆是否禁止
		this.hasDisable = true;

		// 渲染虚拟摇杆UI
		this.renderUI();
	}

	// 允许虚拟摇杆操作
	enable() {
		this.hasDisable = false;
	}

	// 禁止虚拟摇杆操作
	disable() {
		this.hasDisable = true;
		this.onTouchUp();
	}

	/**
	 * 将点的运动限制在一个圆内
	 */
	getPointInCircle(center, r, x, y) {
		let resultX = x;
		let resultY = y;
		let offsetX = center.x - x;
		let offsetY = center.y - y;

		let tan  = Math.atan2(offsetX,offsetY);
		let maxX = Math.sin(tan) * r;
		let maxY = Math.cos(tan) * r;

        
        let degree = (360 + parseInt(""+Util.convertRadian2Degree(tan))) % 360;

		if ( Math.abs(offsetX) > Math.abs(maxX) )
			resultX = center.x - maxX;

		if ( Math.abs(offsetY) > Math.abs(maxY) )
			resultY = center.y -  maxY;

		return { resultX, resultY, degree, radian: Util.convertDegree2Radian(degree)};
	}

	renderUI() {
        let JOYSTICKWIDTH = this.config.joystick_width,WRAPPER_X = this.config.joystick_position_x,WRAPPER_Y=this.config.joystick_position_y;
		this.radius = JOYSTICKWIDTH / 2;

		let img = Util.createSprite({img:this.config.joystick_wrap_img,align:'center',width:this.config.joystick_width,height:this.config.joystick_height});
		img.name = "joybg";
       
        img.x      	= WRAPPER_X;
        img.y      	= WRAPPER_Y;
		this.wrap = img;
        this.wrap.name = 'wrap';
		this.addChild(img);
        this.on(Laya.Event.MOUSE_DOWN,this, this.onTouchDown);
		//this.addChild(wrap);

        this.center = {
			x: WRAPPER_X,
            y: WRAPPER_Y
        }

        this.button = Util.createSprite({img:YYYConfig.instance.joystick_button_img,align:'center',width:90,height:90});
		//this.button.radius = 45;
		this.button.name = "mm_button";


        this.button.x = WRAPPER_X;
        this.button.y = WRAPPER_Y;
        this.addChild(this.button);
	}

	bindEventHandler() {
        this.offEventHandler();

		Laya.stage.on(MOVE,this, this.onTouchMove);
        Laya.stage.on(UP,this, this.onTouchUp);
        //this.wrap.on(Laya.Event.MOUSE_OUT,this, this.upCbk);
	}

	offEventHandler() {
		Laya.stage.off(MOVE,this, this.onTouchMove);
        Laya.stage.off(UP,this, this.onTouchUp);
        //this.wrap.off(Laya.Event.MOUSE_OUT,this, this.upCbk);
	}

	onTouchDown(evt) {
		// 防止多点触控
		if ( this.touchId !== -1 )
			return;
		this.touchId = evt.touchId;
		this.wrap.alpha = 0.3;
		if ( this.tweener ) {
			this.tweener.clear();
			this.tweener = null;
		}

		let bx = evt.stageX;
		let by = evt.stageY;

		this.lastStageX = bx;
		this.lastStageY = by;

		let limit  = this.getPointInCircle(this.center, this.radius, bx, by);

		this.button.x = limit.resultX;
		this.button.y = limit.resultY;

		this.bindEventHandler();
	}

	onTouchUp() {
		this.touchId        = -1;
		this.wrap.alpha = 1;
		// 小圆点缓慢回到中心
        this.tweener = Laya.Tween.to(
            this.button,
            this.center,
            250,
           Laya.Ease.circOut
        );

		this.offEventHandler();

		if ( !this.hasDisable ) {
			this.event(Laya.Event.MOUSE_UP,-9999);
        }
	}

    eventFilter(limit) {
        let degree = limit.degree;
        let low  = this.currentDegree - this.halfDirection;
        let high = this.currentDegree + this.halfDirection;

        if ( degree >= low && degree < high ) {
            return false;
        } else {
            this.currentDegree = Math.ceil(degree / this.directionDegree) * this.directionDegree;
            limit.radian = Util.convertDegree2Radian(this.currentDegree);
            this.event(Laya.Event.MOUSE_MOVE,limit);
        }
    }

	onTouchMove(evt) {

        // if ( this.currIdentifier !== undefined && evt.data.identifier !== this.currIdentifier ) {
        //     return;
        // }

        // this.currIdentifier = evt.data.identifier;

        let bx = evt.stageX;
		let by = evt.stageY;

		this.lastStageX = bx;
		this.lastStageY = by;

		let limit = this.getPointInCircle(this.center, this.radius, bx, by);

		this.button.x = limit.resultX;
		this.button.y = limit.resultY;

        if ( !this.hasDisable ) {
            this.eventFilter(limit);
        }
	}
}

